package logic;

import java.util.List;
import java.util.LinkedList;

public class Production{
    private List<Simbol> simbols;
    private List<SintaxRule> srsimbols;
    
    public Production (){
    	this.simbols=new LinkedList<Simbol>();
    	this.srsimbols=new LinkedList<SintaxRule>();
    }
    
    public List<Simbol> getSimbols(){
    	return this.simbols;
    }

    public void addSimbol(Simbol s){
    	this.simbols.add(s);
    }
    
    public void addFinalSimbol(Simbol s){
    	this.addSimbolAt(s, 0);
    }
    
    public void addSimbolAt(Simbol s, int pos){
    	this.simbols.add(pos, s);
    }
    
    public List<SintaxRule> getSRSimbols(){
    	return this.srsimbols;
    }
    
    public boolean contains(String s){
    	boolean cont=false;
    	for(int i=0;i<simbols.size();i++)
    		if(simbols.get(i).equals(s))
    			cont=true;
    	return cont;
    }
    
    public boolean isEmpty(){
    	boolean res=true;
    	if(simbols.size()>0 || srsimbols.size()>0)
    		res=false;
    	return res;
    }

    public void addSRSimbol(SintaxRule sr){
    	this.srsimbols.add(sr);
    }

    public void addTerms(List<Simbol> simbols, List<SintaxRule> srsimbols){
		SintaxRule sr;
		int srsize=this.srsimbols.size();
		for(int i=0;i<srsimbols.size();i++){
		    sr=srsimbols.get(i);
		    sr.setPosition(sr.getPosition()+srsize);
		    this.srsimbols.add(sr);
		}
	
		for(int i=0;i<simbols.size();i++)
		    this.simbols.add(simbols.get(i));
    }
    
    public SintaxRule getRepSRSimbol(){
    	SintaxRule repSR=null;
    	for(int s=0; s<srsimbols.size() && repSR==null; s++)
    		if(srsimbols.get(s).getType().equals("repeated"))
    			repSR=srsimbols.get(s);
    	return repSR;
    }
    
    public String repetitionSide(){
    	String side="";
    	if(haveRepetition())
    		for(int s=0; s<srsimbols.size(); s++)
        		if(srsimbols.get(s).getType().equals("repeated"))
        			if(srsimbols.get(s).getPosition()==1)
        				side="right";
        			else if(srsimbols.get(s).getPosition()==0)
        				side="left";
        			
    	return side;
    }
    
    public boolean haveRepetition(){
    	boolean rep=false;
    	for(int s=0;s<srsimbols.size() && !rep;s++)
    		if(srsimbols.get(s).getType().equals("repeated"))
    			rep=true;
    	
    	return rep;	
    }
    
    public Production clone(){
    	Production p=new Production();
    	for (int i=0;i<this.getSimbols().size();i++)
    		p.addSimbol(this.getSimbols().get(i));
    	for (int i=0;i<this.getSRSimbols().size();i++)
    		p.addSRSimbol(this.getSRSimbols().get(i).clone());
    	return p;
    }
    
    public void reverse(){
    	List<Simbol> nueva=new LinkedList<Simbol>();
    	for(int i=simbols.size()-1;i>=0;i--)
    		nueva.add(simbols.get(i));
    	
    	this.simbols=nueva;
    }
    
    public String getConway(String nodo1, String nodo2, int n, String src){
		String conway="";
		int sims=simbols.size()-1, srs=srsimbols.size()-1, cont=0;
		while(cont < simbols.size()+srsimbols.size()){
		    if(srsimbols.size()>0 && srsimbols.get(srs).getPosition()==cont){
				conway+="node"+srs+""+sims+"in [shape=point];\n";
				conway+="node"+srs+""+sims+"out [shape=point];\n";
				conway+=srsimbols.get(srs).getConway("node"+srs+""+sims+"in", "node"+srs+""+sims+"out");
		
				if(cont+1 < simbols.size()+srsimbols.size())
				    conway+="internode"+n+src+cont+" [shape=point];\n";
				if(cont>0)
				    conway+="internode"+n+src+(cont-1)+" -> node"+srs+""+sims+"in;\n";
				else if (cont==0)
				    conway+=nodo1+" -> node"+srs+""+sims+"in;\n";
				if(cont+1 < simbols.size()+srsimbols.size())
				    conway+="node"+srs+""+sims+"out -> internode"+n+src+cont+";\n";
				else
				    conway+="node"+srs+""+sims+"out -> "+nodo2+";\n";
		
				if(srs-1>=0)
				   srs--;
		    }else if(simbols.size()>0){
		    	simbols.get(sims).setId("snode"+n+cont+src+sims+simbols.get(sims).getValue());
				conway+=simbols.get(sims).getConway();

				if(cont+1 < simbols.size()+srsimbols.size())
				    conway+="internode"+n+src+cont+" [shape=point];\n";
				if(cont>0)
				    conway+="internode"+n+src+(cont-1)+" -> "+simbols.get(sims).getId()+";\n";
				else if (cont==0)
				    conway+=nodo1+" -> "+simbols.get(sims).getId()+";\n";
				if(cont+1 < simbols.size()+srsimbols.size())
				    conway+=simbols.get(sims).getId()+" -> internode"+n+src+cont+";\n";
				else
				    conway+=simbols.get(sims).getId()+" -> "+nodo2+";\n";
		
				
				/*
				if(cont+1 < simbols.size()+srsimbols.size())
				    conway+="internode"+n+src+cont+" [shape=point];\n";
				if(cont>0)
				    conway+="internode"+n+src+(cont-1)+" -> "+simbols.get(sims).getValue()+";\n";
				else if (cont==0)
				    conway+=nodo1+" -> "+simbols.get(sims).getValue()+";\n";
				if(cont+1 < simbols.size()+srsimbols.size())
				    conway+=simbols.get(sims).getValue()+" -> internode"+n+src+cont+";\n";
				else
				    conway+=simbols.get(sims).getValue()+" -> "+nodo2+";\n";
				*/
				if(sims-1>=0)
				    sims--;
		    }
		    cont++;
		}
	
		return conway;
    }

    public String toString(){
		int length=simbols.size()+srsimbols.size();
		int size=simbols.size()-1;
		String s="";
		
		if(simbols.size()>0 || srsimbols.size()>0){
		    for(int i=length;i>=0;i--){
			for(int j=0;j<srsimbols.size();j++){
			    if(srsimbols.get(j).getPosition()==(length-i)){
				s+=srsimbols.get(j).toString();
			    }
			}
	
			if(size>=0)s+=simbols.get(size--).toString();
				
		    }
		}
	
		return s;
    }

}